﻿// Vex Flow Notation
// Author Larry Kuhns 2011
// Implements Repetitions (Coda, signo, D.C., etc.)
//
// Requires vex.js.

/** 
 * @constructor 
 */
Vex.Flow.Repetition = function(type, x, y_shift) { 
  if (arguments.length > 0) this.init(type, x, y_shift); 
}

Vex.Flow.Repetition.type = {

  NONE: 1,         // no coda or segno
  CODA_LEFT: 2,    // coda at beginning of stave
  CODA_RIGHT: 3,   // coda at end of stave
  SEGNO_LEFT: 4,   // segno at beginning of stave
  SEGNO_RIGHT: 5,  // segno at end of stave
  DC: 6,           // D.C. at end of stave
  DC_AL_CODA: 7,   // D.C. al coda at end of stave
  DC_AL_FINE: 8,   // D.C. al Fine end of stave
  DS: 9,           // D.S. at end of stave
  DS_AL_CODA: 10,  // D.S. al coda at end of stave
  DS_AL_FINE: 11,  // D.S. al Fine at end of stave
  FINE: 12         // Fine at end of stave
};

Vex.Flow.Repetition.prototype = new Vex.Flow.StaveModifier();
Vex.Flow.Repetition.prototype.constructor = Vex.Flow.Repetition;
Vex.Flow.Repetition.superclass = Vex.Flow.StaveModifier.prototype;

Vex.Flow.Repetition.prototype.init = function(type, x, y_shift) {
  var superclass = Vex.Flow.Repetition.superclass;
  superclass.init.call(this);


  this.symbol_type = type;
  this.x = x;
  this.x_shift = 0;
  this.y_shift = y_shift;
  this.font = {
    family: "times",
    size: 12,
    weight: "bold italic"
  }
}

Vex.Flow.Repetition.prototype.getCategory = function() {return "repetitions";}

Vex.Flow.Repetition.prototype.setShiftX = function(x) {
  this.x_shift = x; return this;
}
Vex.Flow.Repetition.prototype.setShiftY = function(y) {
  this.y_shift = y; return this;
}

Vex.Flow.Repetition.prototype.draw = function(stave, x) {

  switch (this.symbol_type) {
    case Vex.Flow.Repetition.type.CODA_RIGHT:
      this.drawCodaFixed(stave, x + stave.width);
      break;
    case Vex.Flow.Repetition.type.CODA_LEFT:
      this.drawSymbolText(stave, x, "Coda", true);
      break;
    case Vex.Flow.Repetition.type.SEGNO_LEFT:
      this.drawSignoFixed(stave, x);
      break;
    case Vex.Flow.Repetition.type.SEGNO_RIGHT:
      this.drawSignoFixed(stave, x + stave.width);
      break;
    case Vex.Flow.Repetition.type.DC:
      this.drawSymbolText(stave, x, "D.C.", false);
      break;
    case Vex.Flow.Repetition.type.DC_AL_CODA:
      this.drawSymbolText(stave, x, "D.C. al", true);
      break;
    case Vex.Flow.Repetition.type.DC_AL_FINE:
      this.drawSymbolText(stave, x, "D.C. al Fine", false);
      break;
    case Vex.Flow.Repetition.type.DS:
      this.drawSymbolText(stave, x, "D.S.", false);
      break;
    case Vex.Flow.Repetition.type.DS_AL_CODA:
      this.drawSymbolText(stave, x, "D.S. al", true);
      break;
    case Vex.Flow.Repetition.type.DS_AL_FINE:
      this.drawSymbolText(stave, x, "D.S. al Fine", false);
      break;
    case Vex.Flow.Repetition.type.FINE:
      this.drawSymbolText(stave, x, "Fine", false);
      break;
    default:
      break;
  }

  return this;
}

Vex.Flow.Repetition.prototype.drawCodaFixed = function(stave, x) {
  if (!stave.context) throw new Vex.RERR("NoCanvasContext",
      "Can't draw stave without canvas context.");

  var y = stave.getYForTopText(stave.options.num_lines) + this.y_shift;
  Vex.Flow.renderGlyph(stave.context, this.x + x + this.x_shift, 
                       y + 25, 40, "v4d", true);
  return this;
}

Vex.Flow.Repetition.prototype.drawSignoFixed = function(stave, x) {
  if (!stave.context) throw new Vex.RERR("NoCanvasContext",
      "Can't draw stave without canvas context.");
  var y = stave.getYForTopText(stave.options.num_lines) + this.y_shift;
  Vex.Flow.renderGlyph(stave.context, this.x + x + this.x_shift, 
                       y + 25, 30, "v8c", true);
  return this;
}

Vex.Flow.Repetition.prototype.drawSymbolText = function(stave, x, text, draw_coda) {
  if (!stave.context) throw new Vex.RERR("NoCanvasContext",
      "Can't draw stave without canvas context.");

  var ctx = stave.context;
  ctx.save();
  ctx.setFont(this.font.family, this.font.size, this.font.weight);
    // Default to right symbol
  var text_x = 0 + this.x_shift;
  var symbol_x = x + this.x_shift;
  if (this.symbol_type == Vex.Flow.Repetition.type.CODA_LEFT) {
      // Offset Coda text to right of stave beginning
    text_x = this.x + stave.options.vertical_bar_width;
    symbol_x = text_x + ctx.measureText(text).width + 12;
  } else {
      // Offset Signo text to left stave end
    symbol_x = this.x + x + stave.width - 5 + this.x_shift;
    text_x = symbol_x - + ctx.measureText(text).width - 12;
  }
  var y = stave.getYForTopText(stave.options.num_lines) + this.y_shift;
  if (draw_coda) {
    Vex.Flow.renderGlyph(ctx, symbol_x, y, 40, "v4d", true);
  }
  
  ctx.fillText(text, text_x, y + 5);
  ctx.restore();

  return this;
}